package lnk

import (
	"bytes"
	"io"
	"strings"

	"github.com/olekukonko/tablewriter"
)

//IconEnvironmentDataBlock
//BlockSize (4 bytes): A 32-bit, unsigned integer that specifies the size of the IconEnvironmentDataBlock structure. This value MUST be 0x00000314.
//BlockSignature (4 bytes): A 32-bit, unsigned integer that specifies the signature of the IconEnvironmentDataBlock extra data section. This value MUST be 0xA0000007.
//TargetAnsi (260 bytes): A NULL-terminated string, defined by the system default code page, which specifies a path that is constructed with environment variables.
//TargetUnicode (520 bytes): An optional, NULL-terminated, Unicode string that specifies a path that is constructed with environment variables.
type IconEnvironmentDataBlock struct {
	size          uint32
	signature     uint32
	TargetAnsi    string
	TargetUnicode string
}

func (t *IconEnvironmentDataBlock) BlockSize() uint32 {
	return t.size
}

func (t *IconEnvironmentDataBlock) BlockSignature() uint32 {
	return t.signature
}

func (t *IconEnvironmentDataBlock) BlockType() string {
	return blockSignature(t.signature)
}

// String prints the TrackerDataBlock in a table.
func (t IconEnvironmentDataBlock) String() string {
	var sb strings.Builder

	table := tablewriter.NewWriter(&sb)
	table.SetAlignment(tablewriter.ALIGN_LEFT)
	table.SetRowLine(true)

	table.SetHeader([]string{"IconEnvironmentDataBlock", "Value"})
	table.Append([]string{"BlockSize", uint32TableStr(t.size)})
	table.Append([]string{"BlockSignature", uint32TableStr(t.signature)})
	table.Append([]string{"BlockType", t.BlockType()})
	table.Append([]string{"TargetAnsi", t.TargetAnsi})
	table.Append([]string{"TargetUnicode", t.TargetUnicode})
	table.Render()

	return sb.String()
}

func ParseIconEnvironmentDataBlock(size, signature uint32, data []byte) (*IconEnvironmentDataBlock, error) {
	r := bytes.NewReader(data)
	d := IconEnvironmentDataBlock{
		size:      size,
		signature: signature,
	}

	targetAnsi := make([]byte, 260)
	_, err := io.ReadFull(r, targetAnsi)
	if err != nil {
		return nil, err
	}
	d.TargetAnsi, _ = GBKDecoder.String(readString(targetAnsi))

	targetUnicode := make([]byte, 520)
	_, err = io.ReadFull(r, targetUnicode)
	if err != nil {
		return nil, err
	}
	d.TargetUnicode = readUnicodeString(targetUnicode)

	return &d, nil
}
